package com.entrogy.service.impl;

import com.entrogy.bean.*;
import com.entrogy.dao.*;
import com.entrogy.service.WeixinService;
import com.entrogy.utils.SendUtils;
import com.entrogy.utils.StrUtils;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class WeixinServiceImpl implements WeixinService {

    private static final Logger logger = LoggerFactory.getLogger(WeixinServiceImpl.class);


    @Value("${visitor.enable}")
    private boolean visitorEnable;

    @Autowired
    private WeixinMapper weixinMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private ParentMapper parentMapper;
    @Autowired
    private MessageMapper messageMapper;
    @Autowired
    private CourseMapper courseMapper;
    @Autowired
    private DepartmentMapper departmentMapper;

    @Autowired
    private VisitMapper visitMapper;

    @Autowired
    private PositionServiceImpl positionService;

    @Override
    public Map<String,Object> insertOpenidandUnionid(String openid, String unionid, String code, Integer identityType) {
        Map<String,Object> map = new HashMap<String, Object>();
        try {
            logger.debug(openid);
            // 先查询该手机号或者openid是否已经在数据库里面了，如果在，说明是老用户，否则为新用户，是新用户则插入一条记录，老用户则返回id
            WeixinEntity weixinEntity = weixinMapper.getWeixinByOpenid(openid);

            if(weixinEntity == null){// 新用户插入一条新的记录
                weixinMapper.insertOpenidandUnionid(openid, unionid);
                weixinEntity = weixinMapper.getWeixinByOpenid(openid);
            }else{
                weixinMapper.updateSessionKey(openid,code);// 老用户每次更新session key
            }
            // 如果unionid为空，且传入的unionid不为空则更新
            if (weixinEntity.getUnionid() == null && !StrUtils.isNullOrEmpty(unionid)) {
                weixinMapper.updateUnionidByOpein(openid, unionid);
            }
            if (!StrUtils.isNullOrEmpty(weixinEntity.getUid())) { // 得到openid对应的user id号
                map.put("uid", weixinEntity.getUid());
                if (weixinEntity.getUid().startsWith("3")) {
                    map.put("type", "parent");
                } else if (weixinEntity.getUid().startsWith("1")) {
                    map.put("type", "teacher");
                } else {
                    map.put("type", "visitor");
                }
            } else {
                map.put("type", "");
            }
            map.put("id", weixinEntity.getId());
            map.put("phone", weixinEntity.getPhone());
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("已关注公众号===>插入opeid和unionid失败"+e.getMessage());
            return new HashMap<>();
        }
        return map;
    }

    @Override
    public Map<String, Object> insertOpenid(String openid) {
        Map<String,Object> map = new HashMap<>();
        try {
            // 如果没有返回说明是新用户，插入一条数据,并返回uid
            WeixinEntity weixinEntity = weixinMapper.getWeixinByOpenid(openid);
            if(weixinEntity == null){
                weixinMapper.insertOpenid(openid);
                weixinEntity = weixinMapper.getWeixinByOpenid(openid);
            }
            if (!StrUtils.isNullOrEmpty(weixinEntity.getUid())) {
                map.put("uid", weixinEntity.getUid());
                map.put("type", "visitor");
            } else {
                map.put("type", "");
            }
            map.put("id", weixinEntity.getId());
            map.put("phone", weixinEntity.getPhone());
        } catch (Exception e) {
            logger.error("未关注公众号===>插入opeid和unionid失败"+e.getMessage());
            return new HashMap<>();
        }
        return map;
    }

    @Override
    public Map<String, Object> sendVerifycode(String phone, String id) {
        Map<String,Object> map = new HashMap<>();
        com.alibaba.fastjson.JSONObject checkInfo = parentMapper.getParentPhoneChangeStatus(phone);
        if (checkInfo != null){
            map.put("changeType", checkInfo.getString("changeType"));
            map.put("teacherPhone", checkInfo.getString("teacherPhone"));
            return map;
        }

        // 根据手机号在数据库中查询
        List<String> type = phoneIdentity(phone);
        // 查询访客开启状态
        Integer visitorEnableStatus = visitMapper.getVisitorEnableStatus();
        if (visitorEnableStatus == 0){
            if (type.contains("2")){
                map.put("isVisitor", "对不起,该手机号和学校预留电话不一致");
                return map;
            }
        }

        //限制一个手机号对应一个微信号(新版本不限制)
        String oldPhone = weixinMapper.selectLoginPhoneWithWeiXinId(id);
        if (!StrUtils.isNullOrEmpty(oldPhone)){
            if (!oldPhone.equals(phone)){
                // 修改此处，不返回微信号和手机号不对应的判断，如果当前微信号已经绑定的手机号和正在登陆的手机号不一致，那么进行和原号码的解绑。
//                map.put("weixinPhoneErrorMsg", "对不起,微信号和手机号不对应");
//                return map;
                parentMapper.updateWeiXinInformation(Integer.valueOf(id));
            }
        }

        try {
            String userId = type.get(1);
            // 将查询到的信息更新到weixin_information表中之前，需要将该用户的id绑定了其他手机号的uid先置位空，这样防止一个用户在不同的小程序上登录报错的情况
            WeixinEntity weixinEntity = weixinMapper.getWeixinByUid(userId);
            if (weixinEntity != null){
                if (!id.equals(weixinEntity.getId())){
                    Integer updateWeiXinInfo = weixinMapper.updateWeiXinByUserId(weixinEntity.getId(), null, null);
                    logger.info("用户ID：" + userId + "使用了不同的小程序登录系统！微信ID：" + weixinEntity.getId());
                }
            }
            // 将查询到的信息更新到weixin_information表中
            weixinMapper.insertWeixinUid(id, userId);

            // 生成4为随机数
            int randNum = (int) ((Math.random() * 9 + 1) * 1000);
            String[] params = { randNum + "" };
            boolean flag = haveUnionid(type.get(1));
            SendUtils.sendByShortMessage(phone, params, 368358 + "");
            if (type.get(0).equals("3") && flag) {
                map.put("type", "parent");
                map.put("uid", type.get(1));
            } else if (type.get(0).equals("1") && flag) {
                map.put("type", "teacher");
                map.put("uid", type.get(1));
            } else {
                map.put("type", "visitor");
                map.put("uid", type.get(1));
                weixinMapper.insertVisitorPhone(type.get(1), phone);//插入游客手机号码
            }
            map.put("verifycode", randNum);
            return map;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("小程序登录验证失败"+e.toString());
            return new HashMap<>();
        }
    }
    // 教师家长登陆 ,返回uid和type类型
    // 1.如果是第一次登录，只有id传上来
    @Override
    public Map<String, Object> loginWeixin(String id, String nickName, String headUrl) {
        /*
         * 1.得到weixin_information中的id 2.先根据id得到对应的用户id
         * 3.根据用户id查询相应表格，得到登录人信息，并根据传入数据更新到数据库中
         */
        Map<String,Object> map = new HashMap<>();
        WeixinEntity weixinEntity = null;
        weixinEntity = weixinMapper.loginWeixin(id);
        // 如果以下两个字段为空，则说明是第一次登录
        if (weixinEntity != null) {
            if ((StrUtils.isNullOrEmpty(weixinEntity.getNickname()) || StrUtils.isNullOrEmpty(weixinEntity.getHeadurl())) && !StrUtils.isNullOrEmpty(nickName)
                    && !StrUtils.isNullOrEmpty(headUrl)) {
                weixinMapper.updateWeixin(id,nickName,headUrl);
            }
        }
        if (!StrUtils.isNullOrEmpty(weixinEntity.getUid())) {
            map.put("uid", weixinEntity.getUid());
            if (weixinEntity.getUid().startsWith("3") && !StrUtils.isNullOrEmpty(weixinEntity.getUnionid()))
                map.put("type", "parent");
            else if (weixinEntity.getUid().startsWith("1") && !StrUtils.isNullOrEmpty(weixinEntity.getUnionid()))
                map.put("type", "teacher");
            else
                map.put("type", "visitor");
        }
        return map;
    }

    @Override
    public void insertPhone(String uid) {
        WeixinEntity weixinEntity = weixinMapper.getWeixinByUid(uid);
        // TODO 先判断weixinEntity为空则不更新直接返回，适配开发环境
        if (weixinEntity == null){
            return;
        }
        if (StrUtils.isNullOrEmpty(weixinEntity.getPhone())) {
            if (uid.startsWith("3")){
                String phone = parentMapper.getparentById(uid).getParentVisitorPhone();
                int updateWeixinPhoneRow = weixinMapper.updateWeixinPhone(phone);
                weixinMapper.updateParentPhone(uid);
            }
            else if (uid.startsWith("1")){
                // 将该id对应的电话号码的其他登录信息之置空，保证登录信息电话号码的唯一性
                String phone = userMapper.getUserByUid(uid).getMobile();
                int updateWeixinPhoneRow = weixinMapper.updateWeixinPhone(phone);
                weixinMapper.updateTeacherPhone(uid);
            }
        }
    }

    public Boolean haveUnionid(String uid) {
        Integer id = weixinMapper.haveUnionid(uid);
        return id==null?false:true;
    }

    @Override
    public JSONObject getMessageforVisitor() {
        MessageEntity messageEntity = messageMapper.getVisitorMessage(1);//TODO 上线要在数据库加入第一天访客的通知信息
        JSONObject jsonObject = new JSONObject();
        if(messageEntity != null && messageEntity.getMessageId()!=0 && !StrUtils.isNullOrEmpty(messageEntity.getMessageTime())){
            jsonObject.put("id", messageEntity.getMessageId());
            String[] time = messageEntity.getMessageTime().split(" ");
            jsonObject.put("time", time[0]);
            jsonObject.put("author","“熵熵”脸卡通");
            jsonObject.put("title", "温馨提示");
            jsonObject.put("content", "为孩子安全保驾护航，为老师辅助教学，为学校信息、安全提升双重保障。");
        }else {
            jsonObject.put("id", 1);
            jsonObject.put("time", new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
            jsonObject.put("author","“熵熵”脸卡通");
            jsonObject.put("title", "温馨提示");
            jsonObject.put("content", "为孩子安全保驾护航，为老师辅助教学，为学校信息、安全提升双重保障。");
        }
        return jsonObject;
    }

    @Override
    public JSONArray getMessage(String uid, int startPage, int endPage) {
        JSONObject jsonObject = new JSONObject();
        JSONArray jsonArray = new JSONArray();
        List<MessageEntity> msgList = messageMapper.listMessage(uid);
        for (int i = 0; i < msgList.size(); i++) {
            MessageEntity mBean = msgList.get(i);
            jsonObject.put("id", mBean.getMessageId());
            jsonObject.put("title", mBean.getMessageContent().substring(0,
                    mBean.getMessageContent().length() > 20 ? 20 : mBean.getMessageContent().length()));
            String[] time = mBean.getMessageTime().split(" ");
            jsonObject.put("content", mBean.getMessageContent() == null ? "" : mBean.getMessageContent());
            jsonObject.put("time", time[0]);
            jsonObject.put("author", mBean.getTeacherName() == null ? "" : mBean.getTeacherName());
            jsonArray.add(jsonObject);
        }
        return jsonArray;
    }

    @Override
    public int getMessageLength(String uid) {
        List<MessageEntity> msgList = null;
        if (uid.startsWith("3")) {
            List<String> childClassLst = messageMapper.getChildCourseid(uid);
            msgList = getMessageListToParent(childClassLst, 0, -1);
            return msgList.size();
        }
        // 老师
        else if (uid.startsWith("1")) {
            UserEntity userEntity = userMapper.getUserByUid(uid);
            msgList = getMessageListToTeacher(userEntity, 0, -1);
            return msgList.size();
        }
        return 0;
    }

    @Override
    public String getOpenIdByphone(String phone) {
        return weixinMapper.getOpenIdByphone(phone);
    }

    @Override
    public WeixinEntity getWeixinByPhone(String phone) {
        return weixinMapper.getWeixinByPhone(phone);
    }

    // 6获取某个老师能看到的通知给首页
    private List<MessageEntity> getMessageListToTeacher(UserEntity user, int startPage, int endPage) {
        // 分为非群组和群组
        // 非群组的
        String course16 = "NULL";
        String course17 = "NULL";
        String course18 = "NULL";
        if (isGradeHead(user)) {
            String s = user.getGradeId();//获取年级ID
            Set<String> courseIdList = new LinkedHashSet<>();
            courseIdList.add(s);
            courseIdList.add(s.substring(0, 2) + "00000");
            courseIdList.add(s.substring(0, 1) + "000000");
            course16 = "(message_information.duty_id=16 AND message_information.course_id IN("
                    + spliceCourseId(courseIdList) + "))";  //TODO --duty_id 的值
        }
        if (positionService.checkPosition(user.getId(), 16)) {
            String s = user.getClassId();
            Set<String> courseIdList = new LinkedHashSet<>();
            courseIdList.add(s);
            courseIdList.add(s.substring(0, 3) + "0000");
            courseIdList.add(s.substring(0, 2) + "00000");
            courseIdList.add(s.substring(0, 1) + "000000");
            course17 = "(message_information.duty_id=17 AND message_information.course_id IN("
                    + spliceCourseId(courseIdList) + "))";//TODO --duty_id 的值
        }
        // 任课老师特殊点
        List<CourseEntity> teachCourseList = getTeachCourse(user);
        if (teachCourseList.size() > 0) {
            Set<String> courseIdList = new LinkedHashSet<>();
            for (CourseEntity cBean : teachCourseList) {
                String s = cBean.getClassId()+"";
                courseIdList.add(s);
                courseIdList.add(s.substring(0, 3) + "0000");
                courseIdList.add(s.substring(0, 2) + "00000");
                courseIdList.add(s.substring(0, 1) + "000000");
            }
            course18 = "(message_information.duty_id=18 AND message_information.course_id IN("
                    + spliceCourseId(courseIdList) + "))";//TODO --duty_id 的值判定
        }
        List<MessageEntity> mListNoGroup = getMessageListToUser(user.getId(), course16, course17, course18,
                startPage, endPage);
        return mListNoGroup;
    }

    private List<MessageEntity> getMessageListToUser(String id, String course16, String course17, String course18, int startPage, int endPage) {
        String sqlNoGroup = "SELECT DISTINCT message_information.*, user.name, message_template.template_name FROM "
                + "message_information, user, message_template WHERE "
                + "message_information.teacher_id=user.id AND "
                + "message_information.template_id=message_template.template_id AND "
                + "message_information.isgroup=0 AND" + "(" + "(message_information.teacher_id='" + id
                + "') OR (message_information.duty_id=20) OR " + "(message_information.target=0 AND (" + course16
                + " OR " + course17 + " OR " + course18 + ") )" + ")";
        String sqlGroup = "SELECT DISTINCT message_information.*, user.name, '老师通知' AS template_name FROM "
                + "message_information, user, group_information WHERE "
                + "message_information.teacher_id=user.id AND "
                + "group_information.id=message_information.course_id AND " + "message_information.isgroup=1 AND " + "("
                + "(message_information.teacher_id='" + id + "') OR " + "(group_information.staff_list LIKE '%"
                + id + "%')" + ")";
        String sql = "select * from ( (" + sqlNoGroup + ") UNION (" + sqlGroup + ")) AS final "
                + "ORDER BY message_time DESC";
        if (endPage > 0)
            sql += " LIMIT " + startPage + "," + endPage;
        return messageMapper.getMessageListToUser(sql);
    }

    // 是否是年级主任
    private boolean isGradeHead(UserEntity user) {
        String gradeId = user.getGradeId();
        return !StrUtils.isNullOrEmpty(gradeId) && gradeId.endsWith("0000");
    }

    // 判断是否是班主任
//    private boolean isHeadmaster(UserEntity user) {
//        Integer sid = userMapper.findSidByUid(user.getId());
//        return sid != null && sid.equals(16);
//    }

    // 判断是否是任课老师
    private List<CourseEntity> getTeachCourse(UserEntity user){
        String uid = user.getId();
        return courseMapper.getCourseByTeacherId(uid,user.getSchoolCode()+"");
    }
    // 拼接courseid
    private String spliceCourseId(Set<String> courseIdList) {
        // 组装courseid
        StringBuilder courseInStr = new StringBuilder();
        for (String courseId : courseIdList) {
            courseInStr.append("'").append(courseId).append("',");
        }
        if (courseInStr.length() > 0) {
            courseInStr = new StringBuilder(courseInStr.substring(0, courseInStr.length() - 1));
        } else {
            courseInStr = new StringBuilder("null");
        }
        return courseInStr.toString();
    }

    // 获得家长首页的messageList，courseIdList是该家长小孩所在班级的id,小部分有多个孩子
    private List<MessageEntity> getMessageListToParent(List<String> courseIdList, int startPage, int endPage) {
        // 获得家长首页的messageList，courseIdList是该家长小孩所在班级的id,小部分有多个孩子
        // 获取全校性、年级性、班级性的通知
        List<MessageEntity> parentMessageList = new ArrayList<>();
        if(courseIdList.size() > 0){
            parentMessageList = messageMapper.getMessageListToParent(courseIdList, startPage, endPage);
        }
        return parentMessageList;
    }

    /*
     * 1:老师 2:游客 3:家长
     */
    private List<String> phoneIdentity(String phone) {
        List<String> list = new ArrayList<>();
        UserEntity userEntity = userMapper.getUserByMobile(phone);
        if (userEntity != null) {
            list.add("1");
            list.add(userEntity.getId());
            return list;
        }
        ParentVisitorEntity parentVisitorEntity = parentMapper.getParentByPhone(phone);
        if (parentVisitorEntity != null) {
            list.add("3");
            list.add(parentVisitorEntity.getParentVisitorId());
            return list;
        }
        list.add("2");
        list.add("2" + System.currentTimeMillis());
        return list;
    }


}
